package org.easydarwin.easyrtc;


import android.app.Activity;
import android.databinding.DataBindingUtil;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;

import org.easydarwin.conf.Config;
import org.easydarwin.easyrtc.databinding.FragmentPushBinding;
import org.easydarwin.push.EasyPusher;
import org.easydarwin.push.MediaStream;
import org.easydarwin.util.AccountUtil;
import org.easydarwin.util.LogUtil;
import org.easydarwin.util.PreferenceManager;
import org.easydarwin.video.EasyRTSPClient;
import org.easydarwin.video.RTSPClient;


import java.io.IOException;

import static org.easydarwin.easyrtc.TheApp.aio;
import static org.easydarwin.easyrtc.TheApp.bus;

public class PushFragment extends Fragment implements TextureView.SurfaceTextureListener {

    MediaStream mStream;
    FragmentPushBinding binding;
    private boolean isCustom ;

    //===============================play
    private TextureView mSurfaceView;
    protected ResultReceiver mResultReceiver;
    protected int mWidth;
    protected int mHeight;
    protected EasyRTSPClient mStreamRender;
    private boolean needRetry = true;
    private boolean isStopVideo = false;
    private SurfaceTexture mTexture;
    private String playUrl ;
    protected int mType = RTSPClient.TRANSTYPE_TCP;
    protected String mUrl;
    public static final String ARG_PARAM1 = "param1";
    public static final String ARG_PARAM2 = "param2";
    private String ip , port , toAccount , mineAccount;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        LogUtil.i("====================PushFragment---onCreate = ");
        super.onCreate(savedInstanceState);
        isCustom = AccountUtil.isCustom("");
        if(isCustom){
            initDataCratePlay();
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        LogUtil.i("====================PushFragment---onCreateView = ");
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_push, container, false);
        return binding.getRoot();
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        LogUtil.i("====================PushFragment---onViewCreated = ");
        super.onViewCreated(view, savedInstanceState);
        if(!isCustom){
            initViewCreatePush(view);
        }else{
            initViewCreatePlay(view);
        }
    }

    @Override
    public void onDestroy() {
        LogUtil.i("====================PushFragment---onDestroy = ");
        super.onDestroy();
        if(!isCustom){
//            mStream.release();
        }else{
            isStopVideo = true;
            stopRending();
        }
    }

    @Override
    public void onResume() {
        LogUtil.i("====================PushFragment---onResume = ");
        super.onResume();
        if(isCustom){
            resumePlay();
        }
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int i, int i1) {
        if(!isCustom){
            surfaceTexturesAvailablePush(surface);
        }else{
            mTexture = surface;
            startRending(surface);
            playVideo();
        }
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {}

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
        return destoryResoure();
    }

    public boolean destoryResoure(){
        if(!isCustom){
            mStream.release();
            return false;
        }else{
            stopRending();
            return true;
        }
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {}

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        LogUtil.i("===========================PushFragment ---- onSaveInstanceState ");
        if(!isCustom){
            mStream.release();
        }else{
            isStopVideo = true;
            stopRending();
        }
    }


    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if(isCustom){
            playVideo();
        }
    }

    // ======================================push
    private void initViewCreatePush(View view){
        TextureView sv = view.findViewById(R.id.pusher);
        sv.setSurfaceTextureListener(this);
        sv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mStream != null) mStream.autoFocus();
            }
        });

        binding.switchCamera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                mStream.switchCamera();
            }
        });
    }

    private int getDgree() {
        int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break; // Natural orientation
            case Surface.ROTATION_90:
                degrees = 90;
                break; // Landscape left
            case Surface.ROTATION_180:
                degrees = 180;
                break;// Upside down
            case Surface.ROTATION_270:
                degrees = 270;
                break;// Landscape right
        }
        Log.i(Config.TAG,"===================StreamActivity----getDgree = " + degrees);
        return degrees;
    }

    private void sendMessage(String msg) {
        binding.info.append("\n");
        binding.info.append(msg);
    }

    private void showPushMessage(int code) {
        switch (code) {
            case EasyPusher.OnInitPusherCallback.CODE.EASY_ACTIVATE_INVALID_KEY:
                sendMessage("无效Key");
                break;
            case EasyPusher.OnInitPusherCallback.CODE.EASY_ACTIVATE_SUCCESS:
                sendMessage("激活成功");
                break;
            case EasyPusher.OnInitPusherCallback.CODE.EASY_PUSH_STATE_CONNECTING:
                sendMessage("连接中");
                break;
            case EasyPusher.OnInitPusherCallback.CODE.EASY_PUSH_STATE_CONNECTED:
                sendMessage("连接成功");
                break;
            case EasyPusher.OnInitPusherCallback.CODE.EASY_PUSH_STATE_CONNECT_FAILED:
                sendMessage("连接失败");
                break;
            case EasyPusher.OnInitPusherCallback.CODE.EASY_PUSH_STATE_CONNECT_ABORT:
                sendMessage("连接异常中断");
                break;
            case EasyPusher.OnInitPusherCallback.CODE.EASY_PUSH_STATE_PUSHING:
                sendMessage("推流中");
                break;
            case EasyPusher.OnInitPusherCallback.CODE.EASY_PUSH_STATE_DISCONNECTED:
                sendMessage("断开连接");
                break;
            case EasyPusher.OnInitPusherCallback.CODE.EASY_ACTIVATE_PLATFORM_ERR:
                sendMessage("平台不匹配");
                break;
            case EasyPusher.OnInitPusherCallback.CODE.EASY_ACTIVATE_COMPANY_ID_LEN_ERR:
                sendMessage("断授权使用商不匹配");
                break;
            case EasyPusher.OnInitPusherCallback.CODE.EASY_ACTIVATE_PROCESS_NAME_LEN_ERR:
                sendMessage("进程名称长度不匹配");
                break;
        }
    }


    private void surfaceTexturesAvailablePush(SurfaceTexture surfaceTexture){
        try {
            mStream = new MediaStream(getContext().getApplicationContext(), surfaceTexture, aio);
            if(isCustom){
                mStream.setmCameraId( Camera.CameraInfo.CAMERA_FACING_BACK);
            }else{
                mStream.setmCameraId( Camera.CameraInfo.CAMERA_FACING_FRONT);
            }
            mStream.startMedia();
            String id = PreferenceManager.getInstance().getPushID("");
            String ip = PreferenceManager.getInstance().getIP();
            String port = Config.DEFAULT_SERVER_PORT_PUSH;
            String toAccount = PreferenceManager.getInstance().getFriendAccount("");
            String mineAccount = PreferenceManager.getInstance().getAccount();

            boolean flag = AccountUtil.isCustom("");
            if(!flag){
                id = mineAccount +"_" + toAccount;
            }
            LogUtil.i("=============pushFragment==ip = " + ip +"----port = " + port +"--------id = " + id +"---toAccount = " + toAccount + "----mineAccount = " + mineAccount +"-----isCustom = " + flag);

            if(id.isEmpty() || id.length() <= 0){
                LogUtil.i("===============id empty , push stream fail");
                return ;
            }
            mStream.setDgree(getDgree());

            mStream.startStream(ip , port, id,
                    new EasyPusher.OnInitPusherCallback() {
                        @Override
                        public void onCallback(int code) {
                            showPushMessage(code);
                        }
                    });

//            if(AccountUtil.isCustom("")){
//                mStream.switchCamera();
//            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public boolean isPushStreaming(){
        return null != mStream && mStream.isStreaming();
    }

    // ==================================================play
    private void initViewCreatePlay(View view){
        mSurfaceView = view.findViewById(R.id.pusher);
        mSurfaceView.setOpaque(false);
        mSurfaceView.setSurfaceTextureListener(this);
        mResultReceiver = new ResultReceiver(new Handler()) {
            @Override
            protected void onReceiveResult(int resultCode, Bundle resultData) {
                super.onReceiveResult(resultCode, resultData);
                Activity activity = getActivity();
                if (activity == null) return;
                if (resultCode == EasyRTSPClient.RESULT_VIDEO_DISPLAYED) {

                    onVideoDisplayed();
                } else if (resultCode == EasyRTSPClient.RESULT_VIDEO_SIZE) {
                    mWidth = resultData.getInt(EasyRTSPClient.EXTRA_VIDEO_WIDTH);
                    mHeight = resultData.getInt(EasyRTSPClient.EXTRA_VIDEO_HEIGHT);
                } else if (resultCode == EasyRTSPClient.RESULT_TIMEOUT) {
                    new AlertDialog.Builder(getActivity()).setMessage("试播时间到").setTitle("SORRY").setPositiveButton(android.R.string.ok, null).show();
                } else if (resultCode == EasyRTSPClient.RESULT_UNSUPPORTED_AUDIO) {
                    new AlertDialog.Builder(getActivity()).setMessage("音频格式不支持").setTitle("SORRY").setPositiveButton(android.R.string.ok, null).show();
                } else if (resultCode == EasyRTSPClient.RESULT_UNSUPPORTED_VIDEO) {
                    new AlertDialog.Builder(getActivity()).setMessage("视频格式不支持").setTitle("SORRY").setPositiveButton(android.R.string.ok, null).show();
                } else if (resultCode == EasyRTSPClient.RESULT_EVENT) {
                    int errorcode = resultData.getInt("errorcode");
                    if (errorcode != 0) {
                        stopRending();
//                        binding.retry.setVisibility(View.VISIBLE);
                        needRetry = true;
//                        binding.stop.setVisibility(View.GONE);
                    }binding.info.append("\n");
                    binding.info.append(resultData.getString("event-msg"));
                }
            }
        };
    }

    private void onVideoDisplayed() {
        LogUtil.i( String.format("========VIDEO DISPLAYED!!!!%d*%d", mWidth, mHeight));
//        binding.progress.setVisibility(View.GONE);
    }

    private void stopRending() {
        if (mStreamRender != null) {
            mStreamRender.stop();
            mStreamRender = null;
        }
//        binding.retry.setVisibility(View.VISIBLE);
        needRetry = true;
//        binding.stop.setVisibility(View.GONE);
    }

    protected void startRending(SurfaceTexture surface) {
//        binding.retry.setVisibility(View.GONE);
        needRetry = false;
//        binding.stop.setVisibility(View.VISIBLE);

        if (TextUtils.isEmpty(playUrl)){
            return;
        }
        if (mStreamRender != null){
            mStreamRender.stop();
        }

        mStreamRender = new EasyRTSPClient(getContext(), Config.key ,surface,bus, mResultReceiver);
        try {
            mStreamRender.start(playUrl , mType, RTSPClient.EASY_SDK_VIDEO_FRAME_FLAG | RTSPClient.EASY_SDK_AUDIO_FRAME_FLAG, "", "", "");
//            mStreamRender.start("rtsp://114.55.107.180:10554/001001000kim/1.sdp", mType, RTSPClient.EASY_SDK_VIDEO_FRAME_FLAG | RTSPClient.EASY_SDK_AUDIO_FRAME_FLAG, "", "", "");
//            binding.progress.setVisibility(View.VISIBLE);
        } catch (Exception e) {
            e.printStackTrace();
            LogUtil.e("======================" + e.getMessage());
            //Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
            return;
        }
    }

    private void initDataCratePlay(){
        if (getArguments() != null) {
            mUrl = getArguments().getString(ARG_PARAM1);
            mType = getArguments().getInt(ARG_PARAM2);
        }

        ip = PreferenceManager.getInstance().getIP();
        port = Config.DEFAULT_SERVER_PORT_PUSH;
        toAccount = PreferenceManager.getInstance().getFriendAccount("");
        mineAccount = PreferenceManager.getInstance().getAccount();


    }

    private void playVideo(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(!isStopVideo){
                    if(isStopVideo){
                        return ;
                    }
                    LogUtil.i("====================playVideo---isStopVideo = " + isStopVideo +"----needRetry = " + needRetry);
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    if(needRetry && !isStopVideo){
//                        LogUtil.i("====================自动重新加载视频");
                        reTryPlayVideo();
                    }
                }
            }
        }).start();
    }

    private void reTryPlayVideo(){
        stopRending();
        startRending(mTexture);
    }

    private void resumePlay() {
        playUrl = PreferenceManager.getInstance().getPlayUrl("");
        boolean isCostom = AccountUtil.isCustom("");
        if(isCostom){
            playUrl = String.format("rtsp://%s:%s/%s.sdp", ip, port, toAccount +"_" + mineAccount);
        }
        LogUtil.i("========================playFragment -- playUrl = " + playUrl);
        if (!TextUtils.isEmpty(playUrl)){
            if (mTexture != null)
                startRending(mTexture);
        }else{
            stopRending();
        }
    }
}
